using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using HuaRongDaoGame.Models;

namespace HuaRongDaoGame.Services
{
    /// <summary>
    /// 游戏数据服务类
    /// </summary>
    public class GameDataService
    {
        private static readonly string AppDataPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "HuaRongDaoGame"
        );
        private static readonly string SaveGamePath = Path.Combine(AppDataPath, "Saves");
        private static readonly string StatisticsPath = Path.Combine(AppDataPath, "statistics.txt");
        private static readonly string SettingsPath = Path.Combine(AppDataPath, "settings.txt");

        /// <summary>
        /// 静态构造函数，确保目录存在
        /// </summary>
        static GameDataService()
        {
            if (!Directory.Exists(AppDataPath))
            {
                Directory.CreateDirectory(AppDataPath);
            }
            if (!Directory.Exists(SaveGamePath))
            {
                Directory.CreateDirectory(SaveGamePath);
            }
        }

        #region 游戏存档

        /// <summary>
        /// 保存游戏
        /// </summary>
        public static bool SaveGame(GameState gameState, string saveName)
        {
            try
            {
                var saveData = new SaveGameData
                {
                    SaveName = saveName,
                    SaveTime = DateTime.Now,
                    LayoutName = gameState.CurrentLayout != null ? gameState.CurrentLayout.Name : "",
                    GameBoardSnapshot = gameState.GameBoard.GetSnapshot(),
                    MoveCount = gameState.MoveCount,
                    HintCount = gameState.HintCount,
                    StartTime = gameState.StartTime,
                    TotalPauseTime = gameState.TotalPauseTime,
                    Status = gameState.Status
                };
                
                var filePath = Path.Combine(SaveGamePath, string.Format("{0}.txt", saveName));
                SaveGameDataToFile(saveData, filePath);
                
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("保存游戏失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 加载游戏
        /// </summary>
        public static GameState LoadGame(string saveName)
        {
            try
            {
                var filePath = Path.Combine(SaveGamePath, string.Format("{0}.txt", saveName));
                if (!File.Exists(filePath))
                {
                    throw new FileNotFoundException(string.Format("存档文件不存在: {0}", saveName));
                }

                var saveData = LoadGameDataFromFile(filePath);

                // 创建游戏状态
                var gameState = new GameState();
                
                // 恢复布局
                GameLayout layout = null;
                if (!string.IsNullOrEmpty(saveData.LayoutName))
                {
                    layout = ClassicLayouts.GetLayoutByName(saveData.LayoutName);
                }

                // 使用新的恢复方法
                gameState.RestoreFromSaveData(
                    layout,
                    saveData.GameBoardSnapshot,
                    saveData.MoveCount,
                    saveData.HintCount,
                    saveData.StartTime,
                    saveData.TotalPauseTime,
                    saveData.Status
                );

                return gameState;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("加载游戏失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

        /// <summary>
        /// 获取所有存档
        /// </summary>
        public static List<SaveGameInfo> GetAllSaves()
        {
            var saves = new List<SaveGameInfo>();
            
            try
            {
                var files = Directory.GetFiles(SaveGamePath, "*.txt");
                foreach (var file in files)
                {
                    try
                    {
                        var saveData = LoadGameDataFromFile(file);
                        
                        saves.Add(new SaveGameInfo
                        {
                            SaveName = saveData.SaveName,
                            SaveTime = saveData.SaveTime,
                            LayoutName = saveData.LayoutName,
                            MoveCount = saveData.MoveCount,
                            Status = saveData.Status
                        });
                    }
                    catch
                    {
                        // 忽略损坏的存档文件
                    }
                }
            }
            catch
            {
                // 忽略目录访问错误
            }

            return saves;
        }

        /// <summary>
        /// 删除存档
        /// </summary>
        public static bool DeleteSave(string saveName)
        {
            try
            {
                var filePath = Path.Combine(SaveGamePath, string.Format("{0}.txt", saveName));
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("删除存档失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        #endregion

        #region 统计数据

        /// <summary>
        /// 保存统计数据
        /// </summary>
        public static bool SaveStatistics(GameStatistics statistics)
        {
            try
            {
                var lines = new List<string>
                {
                    string.Format("TotalGamesPlayed={0}", statistics.TotalGamesPlayed),
                    string.Format("TotalGamesWon={0}", statistics.TotalGamesWon),
                    string.Format("TotalMoves={0}", statistics.TotalMoves),
                    string.Format("AverageMoves={0}", statistics.AverageMoves),
                    string.Format("BestTime={0}", statistics.BestTime.TotalSeconds),
                    string.Format("BestMoves={0}", statistics.BestMoves),
                    string.Format("TotalTime={0}", statistics.TotalTime.TotalSeconds)
                };
                File.WriteAllLines(StatisticsPath, lines);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("保存统计数据失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 加载统计数据
        /// </summary>
        public static GameStatistics LoadStatistics()
        {
            try
            {
                if (File.Exists(StatisticsPath))
                {
                    var lines = File.ReadAllLines(StatisticsPath);
                    var statistics = new GameStatistics();
                    
                    foreach (var line in lines)
                    {
                        var parts = line.Split('=');
                        if (parts.Length == 2)
                        {
                            var key = parts[0];
                            var value = parts[1];
                            
                            switch (key)
                            {
                                case "TotalGamesPlayed":
                                    int totalGamesPlayed;
                                    if (int.TryParse(value, out totalGamesPlayed))
                                        statistics.TotalGamesPlayed = totalGamesPlayed;
                                    break;
                                case "TotalGamesWon":
                                    int totalGamesWon;
                                    if (int.TryParse(value, out totalGamesWon))
                                        statistics.TotalGamesWon = totalGamesWon;
                                    break;
                                case "TotalMoves":
                                    int totalMoves;
                                    if (int.TryParse(value, out totalMoves))
                                        statistics.TotalMoves = totalMoves;
                                    break;
                                case "AverageMoves":
                                    int averageMoves;
                                    if (int.TryParse(value, out averageMoves))
                                        statistics.AverageMoves = averageMoves;
                                    break;
                                case "BestTime":
                                    double seconds;
                                    if (double.TryParse(value, out seconds))
                                    {
                                        statistics.BestTime = TimeSpan.FromSeconds(seconds);
                                    }
                                    break;
                                case "BestMoves":
                                    int bestMoves;
                                    if (int.TryParse(value, out bestMoves))
                                        statistics.BestMoves = bestMoves;
                                    break;
                                case "TotalTime":
                                    double totalSeconds;
                                    if (double.TryParse(value, out totalSeconds))
                                    {
                                        statistics.TotalTime = TimeSpan.FromSeconds(totalSeconds);
                                    }
                                    break;
                            }
                        }
                    }
                    
                    return statistics;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("加载统计数据失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return new GameStatistics();
        }

        #endregion

        #region 游戏设置

        /// <summary>
        /// 保存游戏设置
        /// </summary>
        public static bool SaveSettings(GameSettings settings)
        {
            try
            {
                var lines = new List<string>
                {
                    string.Format("EnableSound={0}", settings.EnableSound),
                    string.Format("EnableMusic={0}", settings.EnableMusic),
                    string.Format("EnableAnimation={0}", settings.EnableAnimation),
                    string.Format("Difficulty={0}", settings.Difficulty),
                    string.Format("Theme={0}", settings.Theme),
                    string.Format("Language={0}", settings.Language),
                    string.Format("MaxHints={0}", settings.MaxHints),
                    string.Format("AutoSave={0}", settings.AutoSave),
                    string.Format("AutoSaveInterval={0}", settings.AutoSaveInterval)
                };
                File.WriteAllLines(SettingsPath, lines);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("保存设置失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }

        /// <summary>
        /// 加载游戏设置
        /// </summary>
        public static GameSettings LoadSettings()
        {
            try
            {
                if (File.Exists(SettingsPath))
                {
                    var lines = File.ReadAllLines(SettingsPath);
                    var settings = new GameSettings();
                    
                    foreach (var line in lines)
                    {
                        var parts = line.Split('=');
                        if (parts.Length == 2)
                        {
                            var key = parts[0];
                            var value = parts[1];
                            
                            switch (key)
                            {
                                case "EnableSound":
                                    bool enableSound;
                                    if (bool.TryParse(value, out enableSound))
                                        settings.EnableSound = enableSound;
                                    break;
                                case "EnableMusic":
                                    bool enableMusic;
                                    if (bool.TryParse(value, out enableMusic))
                                        settings.EnableMusic = enableMusic;
                                    break;
                                case "EnableAnimation":
                                    bool enableAnimation;
                                    if (bool.TryParse(value, out enableAnimation))
                                        settings.EnableAnimation = enableAnimation;
                                    break;
                                case "Difficulty":
                                    int difficulty;
                                    if (int.TryParse(value, out difficulty))
                                        settings.Difficulty = difficulty;
                                    break;
                                case "Theme":
                                    settings.Theme = value;
                                    break;
                                case "Language":
                                    settings.Language = value;
                                    break;
                                case "MaxHints":
                                    int maxHints;
                                    if (int.TryParse(value, out maxHints))
                                        settings.MaxHints = maxHints;
                                    break;
                                case "AutoSave":
                                    bool autoSave;
                                    if (bool.TryParse(value, out autoSave))
                                        settings.AutoSave = autoSave;
                                    break;
                                case "AutoSaveInterval":
                                    int autoSaveInterval;
                                    if (int.TryParse(value, out autoSaveInterval))
                                        settings.AutoSaveInterval = autoSaveInterval;
                                    break;
                            }
                        }
                    }
                    
                    return settings;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("加载设置失败: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return new GameSettings();
        }

        /// <summary>
        /// 保存自定义布局
        /// </summary>
        public static bool SaveCustomLayout(GameLayout layout)
        {
            try
            {
                var customLayoutsPath = Path.Combine(AppDataPath, "CustomLayouts");
                if (!Directory.Exists(customLayoutsPath))
                {
                    Directory.CreateDirectory(customLayoutsPath);
                }

                var fileName = string.Format("{0}.txt", layout.Name.Replace(" ", "_"));
                var filePath = Path.Combine(customLayoutsPath, fileName);

                var lines = new List<string>();
                lines.Add(string.Format("Name={0}", layout.Name));
                lines.Add(string.Format("Description={0}", layout.Description));
                lines.Add(string.Format("Difficulty={0}", layout.Difficulty));
                lines.Add("Blocks:");

                foreach (var blockDef in layout.BlockDefinitions)
                {
                    lines.Add(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}",
                        blockDef.Id, blockDef.Name, blockDef.X, blockDef.Y, blockDef.Width, blockDef.Height, 
                        blockDef.Color.ToArgb(), blockDef.IsCaoCao));
                }

                File.WriteAllLines(filePath, lines);
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("保存自定义布局失败: {0}", ex.Message));
                return false;
            }
        }

        /// <summary>
        /// 加载自定义布局
        /// </summary>
        public static List<GameLayout> LoadCustomLayouts()
        {
            var layouts = new List<GameLayout>();
            
            try
            {
                var customLayoutsPath = Path.Combine(AppDataPath, "CustomLayouts");
                if (!Directory.Exists(customLayoutsPath))
                {
                    return layouts;
                }

                var files = Directory.GetFiles(customLayoutsPath, "*.txt");
                foreach (var file in files)
                {
                    try
                    {
                        var layout = LoadCustomLayoutFromFile(file);
                        if (layout != null)
                        {
                            layouts.Add(layout);
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine(string.Format("加载布局文件失败 {0}: {1}", file, ex.Message));
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("加载自定义布局失败: {0}", ex.Message));
            }
            
            return layouts;
        }

        /// <summary>
        /// 从文件加载自定义布局
        /// </summary>
        private static GameLayout LoadCustomLayoutFromFile(string filePath)
        {
            try
            {
                var lines = File.ReadAllLines(filePath);
                var layout = new GameLayout("", "", 1);
                var blockDefinitions = new List<BlockDefinition>();
                bool readingBlocks = false;

                foreach (var line in lines)
                {
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    if (line == "Blocks:")
                    {
                        readingBlocks = true;
                        continue;
                    }

                    if (readingBlocks)
                    {
                        var parts = line.Split(',');
                        if (parts.Length >= 8)
                        {
                            var blockDef = new BlockDefinition(
                                int.Parse(parts[0]), // Id
                                parts[1], // Name
                                int.Parse(parts[4]), // Width
                                int.Parse(parts[5]), // Height
                                int.Parse(parts[2]), // X
                                int.Parse(parts[3]), // Y
                                Color.FromArgb(int.Parse(parts[6])), // Color
                                bool.Parse(parts[7]) // IsCaoCao
                            );
                            blockDefinitions.Add(blockDef);
                        }
                    }
                    else
                    {
                        var parts = line.Split('=');
                        if (parts.Length == 2)
                        {
                            var key = parts[0].Trim();
                            var value = parts[1].Trim();

                            switch (key)
                            {
                                case "Name":
                                    layout.Name = value;
                                    break;
                                case "Description":
                                    layout.Description = value;
                                    break;
                                case "Difficulty":
                                    int difficulty;
                                    if (int.TryParse(value, out difficulty))
                                        layout.Difficulty = difficulty;
                                    break;
                            }
                        }
                    }
                }

                layout.BlockDefinitions = blockDefinitions;
                return layout;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("解析布局文件失败: {0}", ex.Message));
                return null;
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 保存游戏数据到文件
        /// </summary>
        private static void SaveGameDataToFile(SaveGameData saveData, string filePath)
        {
            var lines = new List<string>
            {
                string.Format("SaveName={0}", saveData.SaveName),
                string.Format("SaveTime={0}", saveData.SaveTime.ToString("yyyy-MM-dd HH:mm:ss")),
                string.Format("LayoutName={0}", saveData.LayoutName),
                string.Format("MoveCount={0}", saveData.MoveCount),
                string.Format("HintCount={0}", saveData.HintCount),
                string.Format("StartTime={0}", saveData.StartTime.ToString("yyyy-MM-dd HH:mm:ss")),
                string.Format("TotalPauseTime={0}", saveData.TotalPauseTime.TotalSeconds),
                string.Format("Status={0}", saveData.Status.ToString())
            };
            
            // 保存棋盘快照
            if (saveData.GameBoardSnapshot != null)
            {
                lines.Add("GameBoardSnapshot:");
                foreach (var block in saveData.GameBoardSnapshot.Blocks)
                {
                    lines.Add(string.Format("Block:{0},{1},{2},{3},{4},{5}", 
                        block.Id, block.X, block.Y, block.Width, block.Height, block.Name));
                }
            }
            
            File.WriteAllLines(filePath, lines);
        }

        /// <summary>
        /// 从文件加载游戏数据
        /// </summary>
        private static SaveGameData LoadGameDataFromFile(string filePath)
        {
            var lines = File.ReadAllLines(filePath);
            var saveData = new SaveGameData();
            var blocks = new List<Block>();
            bool readingBlocks = false;
            
            foreach (var line in lines)
            {
                if (line == "GameBoardSnapshot:")
                {
                    readingBlocks = true;
                    continue;
                }
                
                if (readingBlocks)
                {
                    if (line.StartsWith("Block:"))
                    {
                        var parts = line.Substring(6).Split(',');
                        if (parts.Length >= 6)
                        {
                            var block = new Block(
                                int.Parse(parts[0]), // Id
                                parts[5], // Name
                                int.Parse(parts[3]), // Width
                                int.Parse(parts[4]), // Height
                                int.Parse(parts[1]), // X
                                int.Parse(parts[2]), // Y
                                Color.Blue, // Default color
                                false // IsCaoCao
                            );
                            blocks.Add(block);
                        }
                    }
                }
                else
                {
                    var parts = line.Split('=');
                    if (parts.Length == 2)
                    {
                        var key = parts[0];
                        var value = parts[1];
                        
                                                    switch (key)
                            {
                                case "SaveName":
                                    saveData.SaveName = value;
                                    break;
                                case "SaveTime":
                                    DateTime saveTime;
                                    if (DateTime.TryParse(value, out saveTime))
                                        saveData.SaveTime = saveTime;
                                    break;
                                case "LayoutName":
                                    saveData.LayoutName = value;
                                    break;
                                case "MoveCount":
                                    int moveCount;
                                    if (int.TryParse(value, out moveCount))
                                        saveData.MoveCount = moveCount;
                                    break;
                                case "HintCount":
                                    int hintCount;
                                    if (int.TryParse(value, out hintCount))
                                        saveData.HintCount = hintCount;
                                    break;
                                case "StartTime":
                                    DateTime startTime;
                                    if (DateTime.TryParse(value, out startTime))
                                        saveData.StartTime = startTime;
                                    break;
                                case "TotalPauseTime":
                                    double seconds;
                                    if (double.TryParse(value, out seconds))
                                    {
                                        saveData.TotalPauseTime = TimeSpan.FromSeconds(seconds);
                                    }
                                    break;
                                case "Status":
                                    GameStatus status;
                                    if (Enum.TryParse(value, out status))
                                    {
                                        saveData.Status = status;
                                    }
                                    break;
                            }
                    }
                }
            }
            
            if (blocks.Count > 0)
            {
                saveData.GameBoardSnapshot = new GameBoardSnapshot { Blocks = blocks };
            }
            
            return saveData;
        }

        #endregion

        #region 数据类

        /// <summary>
        /// 存档数据类
        /// </summary>
        public class SaveGameData
        {
            public string SaveName { get; set; }
            public DateTime SaveTime { get; set; }
            public string LayoutName { get; set; }
            public GameBoardSnapshot GameBoardSnapshot { get; set; }
            public int MoveCount { get; set; }
            public int HintCount { get; set; }
            public DateTime StartTime { get; set; }
            public TimeSpan TotalPauseTime { get; set; }
            public GameStatus Status { get; set; }
        }

        /// <summary>
        /// 存档信息类
        /// </summary>
        public class SaveGameInfo
        {
            public string SaveName { get; set; }
            public DateTime SaveTime { get; set; }
            public string LayoutName { get; set; }
            public int MoveCount { get; set; }
            public GameStatus Status { get; set; }
        }

        /// <summary>
        /// 游戏设置类
        /// </summary>
        public class GameSettings
        {
            public bool EnableSound { get; set; }
            public bool EnableMusic { get; set; }
            public bool EnableAnimation { get; set; }
            public int Difficulty { get; set; }
            public string Theme { get; set; }
            public string Language { get; set; }
            public int MaxHints { get; set; }
            public bool AutoSave { get; set; }
            public int AutoSaveInterval { get; set; }

            public GameSettings()
            {
                EnableSound = true;
                EnableMusic = true;
                EnableAnimation = true;
                Difficulty = 1;
                Theme = "Default";
                Language = "zh-CN";
                MaxHints = 3;
                AutoSave = true;
                AutoSaveInterval = 5; // 分钟
            }
        }

        #endregion
    }
} 